#include "uthash.h"

#include <gnu/libc-version.h>
#include <stdio.h>
#include <unistd.h>

// 使用字符串化操作符将宏值转换为字符串常量
#define STR_HELPER(x) #x
#define STR(x)        STR_HELPER(x)
#define FREE(P) \
    free(P);    \
    P = NULL;

typedef struct hashTable {
    int            key;
    int            val;
    UT_hash_handle hh;
} hashTable;

hashTable* hashtable;

hashTable*
find(int ikey)
{
    hashTable* tmp;
    HASH_FIND_INT(hashtable, &ikey, tmp);
    return tmp;
}

void
insert(int ikey, int ival)
{
    hashTable* it = find(ikey);
    if (it == NULL) {
        hashTable* tmp = malloc(sizeof(hashTable));
        tmp->key       = ikey;
        tmp->val       = ival;
        HASH_ADD_INT(hashtable, key, tmp);
    } else {
        it->val = ival;
    }
}

/**
 * @note: The returned array must be malloced, assume caller calls free().
 */
int*
twoSum(int* nums, int numsSize, int target, int* returnSize)
{
    hashtable = NULL;
    for (int i = 0; i < numsSize; i++) {
        hashTable* it = find(target - nums[i]);
        if (it != NULL) {
            int* ret    = malloc(sizeof(int) * 2);
            ret[0]      = it->val;
            ret[1]      = i;
            *returnSize = 2;
            return ret;
        }
        insert(nums[i], i);
    }
    *returnSize = 0;
    return NULL;
}

int
main()
{
#ifdef __GLIBC__
    printf("glibc version: %s\n", gnu_get_libc_version());
    printf("glibc release: %s\n", gnu_get_libc_release());
#else
    printf("Not using glibc\n");
#endif

    printf("uthash version: %s\n", STR(UTHASH_VERSION));

    int  nums[]   = {2, 7, 11, 15};
    int  target   = 9;
    int  rtnSize  = 0;
    int* rtnArray = twoSum(nums, 4, target, &rtnSize);

    if (NULL != rtnArray) {
        printf("[ ");
        for (int i = 0; i < rtnSize; i++) {
            printf("%d ", rtnArray[i]);
        }
        printf("]\n");
        FREE(rtnArray);
        return EXIT_SUCCESS;
    } else {
        return EXIT_FAILURE;
    }
}